<html>
<head><meta charset="utf-8"><title>foo::* support for merge assist · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html">foo::* support for merge assist</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="192008397"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192008397" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192008397">(Mar 27 2020 at 12:13)</a>:</h4>
<p>Hi, first time posting here, please be gentle.</p>
<p>I'm working on the <a href="https://github.com/rust-analyzer/rust-analyzer/issues/3728" title="https://github.com/rust-analyzer/rust-analyzer/issues/3728">https://github.com/rust-analyzer/rust-analyzer/issues/3728</a> issue and I've managed to gain some level of understanding of how things work on the side of RA (at the moment I also have a lot of trouble with comprehending rowan).</p>
<p>Now, I've an idea for the fix of the above issue, but I'm not sure if the approach is correct, so I'd be grateful if somebody could verify it. I think that the problem is that in the <code>split_prefix</code> function the <code>UseTreeList</code> instance doesn't have the STAR in its syntax. I suppose it might be related to <a href="https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_parser/src/grammar/items/use_item.rs#L22" title="https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_parser/src/grammar/items/use_item.rs#L22">https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_parser/src/grammar/items/use_item.rs#L22</a></p>
<blockquote>
<p>This does not handle cases such as <code>use some::path::*</code></p>
</blockquote>
<p>A quick way to resolve the problem is as <span class="user-mention" data-user-id="133169">@matklad</span>  suggested on GH to simply translate <code>use foo::bar::*</code> to <code>use foo::bar::{*}</code>, so my idea here is to update the <code>split_prefix</code> function to take <code>last_child_or_token</code> of a given <code>UseTree.syntax()</code> and if the found <code>NodeOrToken</code> is of <code>STAR</code> kind I'd put the syntax into a string format, replace <code>*</code> with <code>{*}</code> and make an AST object -- a bit similarly to what <code>make.rs::use_tree</code> does.</p>
<p>I'm not sure if it's a correct approach e.g. maybe there is a simpler way to replace <code>*</code> with <code>{*}</code>? I'd be grateful if somebody could give me a push here to proper direction as I'm still very new to this codebase.</p>



<a name="192010303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192010303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192010303">(Mar 27 2020 at 12:36)</a>:</h4>
<p>I don't think there's a need to change <code>split_prefix</code> function's signature. For <code>use foo::bar::*</code> case, the prefix argument would be <code>foo::bar</code>, and that should be enough to figure out that the desired result is <code>use foo::bar::{*}</code></p>



<a name="192010382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192010382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192010382">(Mar 27 2020 at 12:37)</a>:</h4>
<p>Specifically, I think <code>None =&gt; return self.clone()</code> branch should be change to look if there's <code>self.has_star()</code></p>



<a name="192013900"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192013900" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192013900">(Mar 27 2020 at 13:11)</a>:</h4>
<p>As far as I can tell, right now there isn't a scenario where <code>split_path_prefix</code> would return <code>None</code>, so imo it's not possible to reach the <code>None =&gt; return self.clone()</code> branch. Also the prefix is actually result of <code>common_prefix</code> call (in case of the merge_imports assist), so for <code>use foo::bar::*</code>, prefix passed to <code>split_prefix</code> is not necessarily <code>foo::bar</code>.</p>
<p>For example for a simple case of merging <code>use std::foo::*</code> and <code>use std::bar</code> it goes like this. Here's the prefix:</p>
<div class="codehilite"><pre><span></span>PATH@[5; 8)
  PATH_SEGMENT@[5; 8)
    NAME_REF@[5; 8)
      IDENT@[5; 8) &quot;std&quot;
</pre></div>


<p>And here is the <code>suffix</code> that will be returned by <code>split_path_prefix</code> (for the <code>std::foo::*</code> tree):</p>
<div class="codehilite"><pre><span></span>PATH@[0; 4)
  PATH_SEGMENT@[0; 4)
    NAME_REF@[0; 4)
      IDENT@[0; 4) &quot;foo&quot;
</pre></div>



<a name="192015055"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192015055" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192015055">(Mar 27 2020 at 13:19)</a>:</h4>
<p>It returs <code>None</code> in this case: <code>let parent = prefix.parent_path()?;</code></p>



<a name="192015060"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192015060" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192015060">(Mar 27 2020 at 13:19)</a>:</h4>
<p>The <code>?</code></p>



<a name="192016083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192016083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192016083">(Mar 27 2020 at 13:27)</a>:</h4>
<p>Ohh, sorry, missed the <code>?</code> symbol while skimming through the code.</p>
<p>However in the above case of merging <code>use std::foo::*</code> and <code>use std::bar</code> the <code>parent</code> will have a value (at least that's what debugger has told me):</p>
<div class="codehilite"><pre><span></span>PATH@[5; 14)
  PATH@[5; 8)
    PATH_SEGMENT@[5; 8)
      NAME_REF@[5; 8)
        IDENT@[5; 8) &quot;std&quot;
  COLONCOLON@[8; 10) &quot;::&quot;
  PATH_SEGMENT@[10; 14)
    NAME_REF@[10; 14)
      IDENT@[10; 14) &quot;foo&quot;
</pre></div>



<a name="192016637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192016637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192016637">(Mar 27 2020 at 13:31)</a>:</h4>
<p>Yep, that I think is a slightly different case from when the prefix is equal to the whole path. </p>
<p>I think for this case the fix should be applied around here:</p>
<div class="codehilite"><pre><span></span>let use_tree = make::use_tree(suffix.clone(), self.use_tree_list(), self.alias());
</pre></div>


<p>Here, we also need to preserve <code>self.has_star()</code> (which probably involves adding a boolean parameter to <code>make::use_tree</code>)</p>



<a name="192017880"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192017880" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192017880">(Mar 27 2020 at 13:40)</a>:</h4>
<p>I see, makes sense. One last question for now -  The way <code>UseTree.has_star</code> function works is that it simply fetches <code>children</code> of the given <code>UseTree</code> node and then searches for a <code>T![*]</code>? So if I'd have following tree:</p>
<div class="codehilite"><pre><span></span>USE_TREE@[5; 17)
  PATH@[5; 14)
    PATH@[5; 8)
      PATH_SEGMENT@[5; 8)
        NAME_REF@[5; 8)
          IDENT@[5; 8) &quot;std&quot;
    COLONCOLON@[8; 10) &quot;::&quot;
    PATH_SEGMENT@[10; 14)
      NAME_REF@[10; 14)
        IDENT@[10; 14) &quot;cell&quot;
  COLONCOLON@[14; 16) &quot;::&quot;
  STAR@[16; 17) &quot;*&quot;
</pre></div>


<p>it'd only search the set of direct descendants of the <code>USE_TREE@[5; 17)</code>? ( which here would be<code>PATH@[5; 14)</code>,  <code>COLONCOLON@[14; 16) "::"</code>, <code>STAR@[16; 17) "*"</code>)</p>



<a name="192018148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192018148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192018148">(Mar 27 2020 at 13:42)</a>:</h4>
<p>Indeed, it will look only among direct children (and there can be at most one star among direct children)</p>



<a name="192018407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192018407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192018407">(Mar 27 2020 at 13:44)</a>:</h4>
<p>Great, I finally understand something :D Thanks,  I have everything I need for now, I might get back with more questions later on, but I'll do my best to solve what I can on my own.</p>



<a name="192018716"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192018716" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192018716">(Mar 27 2020 at 13:46)</a>:</h4>
<p><span aria-label="thumbs up" class="emoji emoji-1f44d" role="img" title="thumbs up">:thumbs_up:</span> </p>
<p>The workflow I'd recommend is </p>
<ul>
<li>writing a tests in the assist</li>
<li>using <strong>Rust Analyzer: Run</strong> action to execute the test repatedly</li>
<li>priting the trees to stderr with either <code>"{}"</code> or <code>"{:#?}"</code></li>
</ul>



<a name="192019290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/foo%3A%3A%2A%20support%20for%20merge%20assist/near/192019290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Piotr Szpetkowski <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/foo.3A.3A*.20support.20for.20merge.20assist.html#192019290">(Mar 27 2020 at 13:50)</a>:</h4>
<p>Well, that's basically what I do, I also use the <code>vscode-lldb</code> to trace the code flow as I'm learning what goes where, but so far I haven't found a way to get a format repr of a tree during debug session. Maybe it's just not possible atm.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>